package Client;

import Protobuf.ChatProto;
import io.netty.channel.Channel;
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.SimpleChannelInboundHandler;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.Objects;
import java.util.Scanner;
import java.util.concurrent.*;

public class ClientHandler extends SimpleChannelInboundHandler<ChatProto.Msg> {
    private String username;
    private String psd;
    private static String name;
    private static Long id;
    private static boolean chatFlag = false;


    public static ThreadPoolExecutor exec = new ThreadPoolExecutor(4, 16, 10, TimeUnit.MICROSECONDS,
            new LinkedBlockingDeque<>(), r -> new Thread(r,"ChatThread"+r.hashCode()));

    @Override
    protected void channelRead0(ChannelHandlerContext ctx, ChatProto.Msg msg) throws Exception {

        if(msg.getMsgType()== ChatProto.Msg.MsgType.suc||msg.getMsgType()== ChatProto.Msg.MsgType.res||msg.getMsgType()== ChatProto.Msg.MsgType.logon) {
            switch (msg.getRespLogin().getLoginResult()){
                case loginSuccess:System.out.println(msg.getRespLogin().getPlayer().getId()+"登陆成功");System.out.println("聊天频道： 2.私聊 3.世界 4.队伍 5.工会 6.附近");break;
                case registerSuccess:System.out.println(msg.getRespLogin().getPlayer().getName()+"注册成功");System.out.println("聊天频道： 2.私聊 3.世界 4.队伍 5.工会 6.附近");break;
                case usernameIsExist:System.out.println("账号已存在");break;
                case usernameNotExist:System.out.println("账号不存在");break;
                case passwordError:System.out.println("密码错误");break;
                case otherPlayerLogin:System.out.println("您已在另一处登录");ctx.close();System.exit(0);break;
                default:break;
            }
        }else {
            if(!"".equals(msg.getRespChat().getTime())) {
                System.out.println(msg.getRespChat().getTime());
            }

            String message = msg.getRespChat().getMsg();
            switch (msg.getMsgType()){
                case priChat:message = "[私聊]:"+message;break;
                case worChat:message = "[世界]:"+message;break;
                case teamChat:message = "[队伍]:"+message;break;
                case unionChat:message = "[公会]:"+message;break;
                case mapChat:message = "[附近]:"+message;break;
                default:break;
            }
            if(msg.getRespChat().getChatResult()== ChatProto.RespChat.ChatResult.idIneffective){
                message = "私聊用户不存在";
            }
            String senderName = msg.getRespChat().getSender();
            if(name.equals(senderName)){
                System.out.println("自己"+ message);
            }else {
                System.out.println(msg.getRespChat().getSender() + message);
            }
        }
        if(msg.getMsgType() == ChatProto.Msg.MsgType.suc){
            name = msg.getRespLogin().getPlayer().getName();
            id = msg.getRespLogin().getPlayer().getId();
            chatFlag = true;
        }else if(msg.getMsgType()== ChatProto.Msg.MsgType.res||msg.getMsgType()== ChatProto.Msg.MsgType.logon){
            BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
            ChatProto.Msg.MsgType type = msg.getMsgType();
            init(ctx,type,br);
        }
        if(chatFlag) {
            exec.execute(() ->sendMsg(ctx));
        }
    }

    @Override
    public void channelActive(ChannelHandlerContext ctx) throws Exception {
        System.out.println("请登录(1)或注册(0)账号");
        BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
        ChatProto.Msg.MsgType type = null;
        try {
            type = ChatProto.Msg.MsgType.forNumber(Integer.parseInt(br.readLine()));
        } catch (IOException e) {
            e.printStackTrace();
        }
        init(ctx,type,br);
    }

    public synchronized void sendMsg(ChannelHandlerContext ctx){
        Scanner sc = new Scanner(System.in);
        int type = sc.nextInt();
        boolean input = true;
        while(input){
            if(type>1&&type<7||type == -1) {
                input = false;
            }else {
                System.out.println("请输入2.私聊 3.世界 4.队伍 5.工会 6.附近");
                type = sc.nextInt();
            }
        }
        if(type == -1){
            ctx.channel().close();

        }
        long receiver = 0L;
        if(type == ChatProto.Msg.MsgType.priChat.ordinal()){
            System.out.print("请输入接收人id：");
            receiver = sc.nextLong();
        }
        String information= sc.next();
        ChatProto.Msg msg= ChatProto.Msg.newBuilder()
                .setMsgType(ChatProto.Msg.MsgType.forNumber(type)).setChat(ChatProto.Chat.newBuilder()
                        .setSenderId(id).setSenderName(name).setReceiver(receiver)
                        .setMsg(information).setSendSuc(0).build())
                .build();
        ctx.writeAndFlush(msg);
    }

    private void register(ChannelHandlerContext ctx,BufferedReader br) throws Exception {
        System.out.println("请依次输入");
        System.out.println("账号：");
        username= br.readLine();
        System.out.println("密码：");
        psd=br.readLine();
        System.out.println("昵称：");
        name=br.readLine();
        ChatProto.Msg register = ChatProto.Msg.newBuilder().setMsgType(ChatProto.Msg.MsgType.res)
                .setRegister(ChatProto.Register.newBuilder().setUsername(username).setPsd(psd).setName(name).build())
                .build();
        ctx.writeAndFlush(register);
    }

    private void login(ChannelHandlerContext ctx,BufferedReader br) throws Exception{
        System.out.println("请输入账号:");
        username = br.readLine();
        System.out.println("请输入密码:");
        psd = br.readLine();
        ChatProto.Msg login = ChatProto.Msg.newBuilder().setMsgType(ChatProto.Msg.MsgType.logon)
                .setLogin(ChatProto.Login.newBuilder()
                        .setUsername(username).setPsd(psd).build())
                .build();
        ctx.writeAndFlush(login);
    }

    private void init(ChannelHandlerContext ctx,ChatProto.Msg.MsgType type,BufferedReader br) throws Exception {

        boolean flag = true;
        while (flag) {
            if(type == null){
                type = ChatProto.Msg.MsgType.mapChat;
            }
            switch (Objects.requireNonNull(type)) {
                case res: {
                    register(ctx, br);
                    flag = false;
                    break;
                }
                case logon: {
                    login(ctx, br);
                    flag = false;
                    break;
                }
                default:
                    System.out.println("输入错误，请重新输入(0)注册或(1)登录");
                    type = ChatProto.Msg.MsgType.forNumber(Integer.parseInt(br.readLine()));
                    break;
            }
        }
    }

    @Override
    public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause){
        cause.printStackTrace();
        Channel channel = ctx.channel();
        if(channel.isActive()) {
            ctx.close();
        }
    }

}
